﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

using Ionic.Zip;

namespace MassContentUploader.DataTypes.MassUploader {
    public class ZipHandler {
        private string Path;
        private string Destination;
        private bool Recursive = false;
        private string Password;
        public string[] Errors = new string[] { };
        public string[] Extracted = new string[] { };
        public ReturnCodes Result = ReturnCodes.GenericFailure;

        public enum ReturnCodes { 
            GenericFailure,
            EmptyArchive,
            Success
        }

        public ZipHandler(string zipPath, string destPath, bool recursive, string password){
            this.Path = zipPath;
            this.Destination = destPath;
            this.Recursive = recursive;
            this.Password = password;

            using (ZipFile zip = ZipFile.Read(zipPath)) {
                if (zip.Count == 0) {
                    this.Result = ReturnCodes.EmptyArchive;
                    return;
                }

                foreach (ZipEntry entry in zip) {
                    try {
                        string extractedFilePath = this.Destination + "/" + entry.FileName;

                        if (entry.IsDirectory) {
                            if (this.Recursive) {
                                if (!string.IsNullOrEmpty(password)) {
                                    entry.ExtractWithPassword(this.Destination, ExtractExistingFileAction.OverwriteSilently, password);
                                } else {
                                    entry.Extract(this.Destination, ExtractExistingFileAction.OverwriteSilently);
                                }
                            }
                        } else {
                            if (!string.IsNullOrEmpty(password)) {
                                entry.ExtractWithPassword(this.Destination, ExtractExistingFileAction.OverwriteSilently, password);
                            } else {
                                entry.Extract(this.Destination);
                            }
                        }

                        this.AddExtractedPath(extractedFilePath);
                    } catch (Exception ex) {
                        this.AddError(string.Format("Cannot extract entry '{0}': {1}", entry.FileName, ex.Message));
                    }
                }

                if (this.Extracted.Length > 0) {
                    this.Result = ReturnCodes.Success;
                }
            }
        }

        private void AddError(string error) {
            Array.Resize<string>(ref this.Errors, this.Errors.Length + 1);
            this.Errors[this.Errors.Length - 1] = error;
        }

        private void AddExtractedPath(string path) {
            Array.Resize<string>(ref this.Extracted, this.Extracted.Length + 1);
            this.Extracted[this.Extracted.Length - 1] = path;
        }
    }
}